#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../rtai_shmem.h"

// 存储界面元素的结构体
typedef struct {
    GtkWidget *grid;
    GtkWidget **id_labels;
    GtkWidget **name_labels;
    GtkWidget **type_labels;
    GtkWidget **value_labels;
    GtkWidget **hex_labels;
    GtkWidget **entry_widgets;
    GtkWidget **buttons;
    int data_count;
    gboolean initialized;  // 标记控件是否已初始化
} UIData;

// 全局变量
UIData ui_data = {0, FALSE};
// SharedMemory *shm_ptr;

// 数据类型到字符串的转换
const char* type_to_string(DataType type) {
    switch(type) {
        case TYPE_INT: return "INT";
        case TYPE_DINT: return "DINT";
        case TYPE_FLOAT: return "FLOAT";
        case TYPE_DOUBLE: return "DOUBLE";
        case TYPE_STRING: return "STRING";
        case TYPE_UINT: return "UINT";
        case TYPE_UDINT: return "UDINT";
        default: return "UNKNOWN";
    }
}

// 更新显示数据的回调函数
gboolean update_display(gpointer data) {
    if (!shm_ptr || !ui_data.initialized) return G_SOURCE_CONTINUE;
    
    // 只更新控件值，不重建控件
    for (int i = 0; i < ui_data.data_count; i++) {
        char buffer[256];
        int valid = (i < shm_ptr->index);
        
        // 更新名称
        gtk_label_set_text(GTK_LABEL(ui_data.name_labels[i]), 
                          valid ? shm_ptr->data[i].name : "");
        
        // 更新类型
        gtk_label_set_text(GTK_LABEL(ui_data.type_labels[i]),
                          valid ? type_to_string(shm_ptr->data[i].type) : "");
        
        // 更新值
        if (!valid) {
            buffer[0] = '\0';
        } else {
            switch(shm_ptr->data[i].type) {
                case TYPE_INT:
                    sprintf(buffer, "%d", shm_ptr->data[i].value.int32);
                    break;
                case TYPE_DINT:
                    sprintf(buffer, "%ld", shm_ptr->data[i].value.int64);
                    break;
                case TYPE_FLOAT:
                    sprintf(buffer, "%.2f", shm_ptr->data[i].value.float32);
                    break;
                case TYPE_DOUBLE:
                    sprintf(buffer, "%.2lf", shm_ptr->data[i].value.double64);
                    break;
                case TYPE_STRING:
                    sprintf(buffer, "%s", shm_ptr->data[i].value.str);
                    break;
                case TYPE_UINT:
                    sprintf(buffer, "%u", shm_ptr->data[i].value.uint32);
                    break;
                case TYPE_UDINT:
                    sprintf(buffer, "%lu", shm_ptr->data[i].value.uint64);
                    break;
                default:
                    sprintf(buffer, "N/A");
            }
        }
        gtk_label_set_text(GTK_LABEL(ui_data.value_labels[i]), buffer);
        
        // 更新16进制值
        if (!valid) {
            buffer[0] = '\0';
        } else if (shm_ptr->data[i].type == TYPE_INT || 
            shm_ptr->data[i].type == TYPE_DINT ||
            shm_ptr->data[i].type == TYPE_UINT ||
            shm_ptr->data[i].type == TYPE_UDINT) {
            switch(shm_ptr->data[i].type) {
                case TYPE_INT:
                    sprintf(buffer, "0x%X", shm_ptr->data[i].value.int32);
                    break;
                case TYPE_DINT:
                    sprintf(buffer, "0x%lX", shm_ptr->data[i].value.int64);
                    break;
                case TYPE_UINT:
                    sprintf(buffer, "0x%X", shm_ptr->data[i].value.uint32);
                    break;
                case TYPE_UDINT:
                    sprintf(buffer, "0x%lX", shm_ptr->data[i].value.uint64);
                    break;
                default:
                    sprintf(buffer, "N/A");
            }
        } else {
            buffer[0] = '\0';
        }
        gtk_label_set_text(GTK_LABEL(ui_data.hex_labels[i]), buffer);
    }
    
    return G_SOURCE_CONTINUE;
}

// 按钮点击回调函数
void on_button_clicked(GtkWidget *widget, gpointer data) {
    int index = GPOINTER_TO_INT(data);
    const char *entry_text = gtk_entry_get_text(GTK_ENTRY(ui_data.entry_widgets[index]));
    
    if (strlen(entry_text) == 0) return;

    // 根据数据类型更新值
    switch(shm_ptr->data[index].type) {
        case TYPE_INT: {
            int value;
            if (strncmp(entry_text, "0x", 2) == 0) {
                value = (int)strtol(entry_text, NULL, 16);
            } else {
                value = atoi(entry_text);
            }
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
        case TYPE_DINT: {
            long value;
            if (strncmp(entry_text, "0x", 2) == 0) {
                value = strtol(entry_text, NULL, 16);
            } else {
                value = atol(entry_text);
            }
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
        case TYPE_UINT: {
            unsigned int value;
            if (strncmp(entry_text, "0x", 2) == 0) {
                value = (unsigned int)strtoul(entry_text, NULL, 16);
            } else {
                value = (unsigned int)atoi(entry_text);
            }
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
        case TYPE_UDINT: {
            unsigned long value;
            if (strncmp(entry_text, "0x", 2) == 0) {
                value = strtoul(entry_text, NULL, 16);
            } else {
                value = (unsigned long)atol(entry_text);
            }
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
        case TYPE_STRING: {
            shmem_write(shm_ptr->data[index].name, (void*)entry_text);
            break;
        }
        case TYPE_FLOAT: {
            float value = atof(entry_text);
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
        case TYPE_DOUBLE: {
            double value = atof(entry_text);
            shmem_write(shm_ptr->data[index].name, &value);
            break;
        }
    }
    
    // 立即更新显示
    update_display(NULL);
}

int main(int argc, char *argv[]) {
    GtkWidget *window;
    GtkWidget *scroll_window;
    
    // 初始化GTK
    gtk_init(&argc, &argv);
    
    // 初始化共享内存
    lxrt_shmem_init();
    
    // 确保共享内存指针有效
    if (!shm_ptr) {
        g_error("Failed to initialize shared memory");
        return 1;
    }
    
    // 确保共享内存已初始化
    if (shm_ptr->index == 0) {
        g_warning("Shared memory is empty");
        // 自动注册测试变量
        int cycle_time = 0;
        shmem_register("cycle_time", TYPE_INT, &cycle_time);
    }
    
    // 创建主窗口
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Shared Memory Viewer");
    gtk_window_set_default_size(GTK_WINDOW(window), 900, 1000);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
    // 创建滚动窗口
    scroll_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(window), scroll_window);
    
    // 创建网格布局
    ui_data.grid = gtk_grid_new();
    gtk_grid_set_column_spacing(GTK_GRID(ui_data.grid), 10);
    gtk_grid_set_row_spacing(GTK_GRID(ui_data.grid), 5);
    gtk_container_add(GTK_CONTAINER(scroll_window), ui_data.grid);
    
    // 创建表头
    GtkWidget *id_header = gtk_label_new("ID");
    GtkWidget *name_header = gtk_label_new("Name");
    GtkWidget *type_header = gtk_label_new("Type");
    GtkWidget *value_header = gtk_label_new("Value");
    GtkWidget *hex_header = gtk_label_new("Hex Value");
    GtkWidget *input_header = gtk_label_new("Input");
    GtkWidget *button_header = gtk_label_new("Action");
    
    gtk_grid_attach(GTK_GRID(ui_data.grid), id_header, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), name_header, 1, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), type_header, 2, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), value_header, 3, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), hex_header, 4, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), input_header, 5, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(ui_data.grid), button_header, 6, 0, 1, 1);
    
    // 显示所有表头
    gtk_widget_show(id_header);
    gtk_widget_show(name_header);
    gtk_widget_show(type_header);
    gtk_widget_show(value_header);
    gtk_widget_show(hex_header);
    gtk_widget_show(input_header);
    gtk_widget_show(button_header);
    
    // 初始化所有数据行控件
    ui_data.data_count = MAX_VAR_NUM;
    ui_data.id_labels = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.name_labels = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.type_labels = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.value_labels = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.hex_labels = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.entry_widgets = calloc(ui_data.data_count, sizeof(GtkWidget*));
    ui_data.buttons = calloc(ui_data.data_count, sizeof(GtkWidget*));
    
    for (int i = 0; i < ui_data.data_count; i++) {
        char buffer[32];
        
        // 序号
        sprintf(buffer, "%d", i);
        ui_data.id_labels[i] = gtk_label_new(buffer);
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.id_labels[i], 0, i+1, 1, 1);
        
        // 名称
        ui_data.name_labels[i] = gtk_label_new("");
        gtk_widget_set_size_request(ui_data.name_labels[i], 200, -1);
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.name_labels[i], 1, i+1, 1, 1);
        
        // 类型
        ui_data.type_labels[i] = gtk_label_new("");
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.type_labels[i], 2, i+1, 1, 1);
        
        // 值
        ui_data.value_labels[i] = gtk_label_new("");
        gtk_widget_set_size_request(ui_data.value_labels[i], 150, -1);
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.value_labels[i], 3, i+1, 1, 1);
        
        // 16进制值
        ui_data.hex_labels[i] = gtk_label_new("");
        gtk_widget_set_size_request(ui_data.hex_labels[i], 150, -1);
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.hex_labels[i], 4, i+1, 1, 1);
        
        // 输入框
        ui_data.entry_widgets[i] = gtk_entry_new();
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.entry_widgets[i], 5, i+1, 1, 1);
        
        // 按钮
        ui_data.buttons[i] = gtk_button_new_with_label("Update");
        g_signal_connect(ui_data.buttons[i], "clicked", 
                        G_CALLBACK(on_button_clicked), GINT_TO_POINTER(i));
        gtk_grid_attach(GTK_GRID(ui_data.grid), ui_data.buttons[i], 6, i+1, 1, 1);
        
        // 显示控件
        gtk_widget_show(ui_data.id_labels[i]);
        gtk_widget_show(ui_data.name_labels[i]);
        gtk_widget_show(ui_data.type_labels[i]);
        gtk_widget_show(ui_data.value_labels[i]);
        gtk_widget_show(ui_data.hex_labels[i]);
        gtk_widget_show(ui_data.entry_widgets[i]);
        gtk_widget_show(ui_data.buttons[i]);
    }
    
    ui_data.initialized = TRUE;
    
    // 显示窗口和所有内容
    gtk_widget_show_all(window);
    
    // 设置定时器，每0.5秒更新一次显示
    g_timeout_add(200, (GSourceFunc)update_display, NULL);
    
    // 立即触发一次更新
    update_display(NULL);
    
    // 运行GTK主循环
    gtk_main();
    
    return 0;
}
